package com.na.report.utils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.SimpleBindings;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;

public class CommonUtils {

	private static final DateFormat DATE_FORMATER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	
	private CommonUtils() {}
	
	public static <T> T newInstanceByJs(Class<T> objClass, String objName, InputStream js) {
		try {
			T obj = objClass.newInstance();
			Map<String, Object> bindings = new HashMap<String, Object>(1);
			bindings.put(objName, obj);
			ScriptEngineManager manager = new ScriptEngineManager();
			ScriptEngine engine = manager.getEngineByName("JavaScript");
			engine.eval(IOUtils.read(js, IOUtils.UTF8), new SimpleBindings(bindings));
			return obj;
		} catch (Exception e) {
		}
		return null;
	}
	
	public static String getRequestAddr(HttpServletRequest req) {
		String addr = req.getHeader("x-forwarded-for");
		if (!StringUtils.isEmpty(addr) && !"unknown".equalsIgnoreCase(addr)) {
			return addr;
		}
		addr = req.getHeader("Proxy-Client-IP");
		if (!StringUtils.isEmpty(addr) && !"unknown".equalsIgnoreCase(addr)) {
			return addr;
		}
		addr = req.getHeader("WL-Proxy-Client-IP");
		if (!StringUtils.isEmpty(addr) && !"unknown".equalsIgnoreCase(addr)) {
			return addr;
		}
		return req.getRemoteAddr();
	}
	
	public static String formatDate(Date date) {
		return DATE_FORMATER.format(date);
	}
	
	public static Date parseDate(String date) {
		try {
			return DATE_FORMATER.parse(date);
		} catch (ParseException e) {
		}
		return null;
	}
	
	public static <T> T wrapServletRequestParameters(ServletRequest req, Class<T> beanClass) {
		try {
			BeanInfo bean = Introspector.getBeanInfo(beanClass, Object.class);
			PropertyDescriptor[] prpts = bean.getPropertyDescriptors();
			T obj = beanClass.newInstance();
			for (PropertyDescriptor p : prpts) {
				String value = req.getParameter(p.getName());
				if (value != null) {
					Method setter = p.getWriteMethod();
					Object _value = castParameterValue(value, p.getPropertyEditorClass());
					setter.invoke(obj, _value);
				}
			}
			return obj;
		} catch (Exception e) {
		}
		return null;
	}
	
	static Object castParameterValue(String parameterValue, Class<?> type) {
		if (type == String.class) {
			return parameterValue;
		}
		if (type == byte.class || type == Byte.class) {
			return Byte.parseByte(parameterValue);
		}
		if (type == boolean.class || type == Boolean.class) {
			return Boolean.parseBoolean(parameterValue);
		}
		if (type == char.class || type == Character.class) {
			return parameterValue.charAt(0);
		}
		if (type == short.class || type == Short.class) {
			return Short.parseShort(parameterValue);
		}
		if (type == int.class || type == Integer.class) {
			return Integer.parseInt(parameterValue);
		}
		if (type == float.class || type == Float.class) {
			return Float.parseFloat(parameterValue);
		}
		if (type == long.class || type == Long.class) {
			return Long.parseLong(parameterValue);
		}
		if (type == double.class || type == Double.class) {
			return Double.parseDouble(parameterValue);
		}
		if (type == Date.class) {
			try {
				return DATE_FORMATER.parse(parameterValue);
			} catch (ParseException e) {
				return null;
			}
		}
		return parameterValue;
	}
	
}
